#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QTime>
#include "sortdialog.h"
namespace Ui {
    class MainWindow;
}

// libqtmultimediakit from Qt Mobility 1.1.3 or later
#include <QMediaPlaylist>
#include <QMediaPlayer>

class QModelIndex;
class PlayListListModel;
class PlaylistModel;
class QAbstractListModel;
class QDeclarativeItem;
class ItemsListModel;
class SubscriptionListModel;

/** A small-screen Playlist View Main Window.
    Originally based on qtmobility-1.1/demos/player. 
    @author Alan Ezust
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

    // width and height of the QML view area.
    Q_PROPERTY(int qmlWidth READ qmlWidth NOTIFY qmlResized);
    Q_PROPERTY(int qmlHeight READ qmlHeight NOTIFY qmlResized);

    // index of playlist item chosen from QML listview
    Q_PROPERTY(int chosenFromQML READ chosenFromQML WRITE setChosenFromQML NOTIFY chosenFromQMLChanged);

    // What the user chose from the drop-down menu
    Q_PROPERTY(QString showOption READ showOption WRITE setShowOption NOTIFY showOptionChanged);

    // Current playlist playing.
    Q_PROPERTY(QString currentM3u READ currentM3u WRITE setCurrentM3u NOTIFY currentM3uChanged);

    // Title of current playlist
    Q_PROPERTY(QString m3uTitle READ m3uTitle WRITE setM3uTitle NOTIFY m3uTitleChanged);

    // True if the play queue is empty
    Q_PROPERTY(bool isQueueEmpty READ isQueueEmpty NOTIFY playListChanged);

    // true if the playlist is empty
    Q_PROPERTY(bool isPlayListEmpty READ isPlayListEmpty NOTIFY playListChanged);

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    static MainWindow* instance();
    void resizeEvent(QResizeEvent * e);
protected:
    // based on order added in designer
    enum {Subscriptions = 4, NowPlaying = 5};
    void saveSettings();
    void restoreSettings();

    void changeEvent(QEvent *e);
    void closeEvent(QCloseEvent *);
signals:
    void changeVolume(int volume);
    void changeMuting(bool muting);
    void qmlResized();
    void playListChanged();
    void showOptionChanged();
    void chosenFromQMLChanged();
    void currentM3uChanged();
    void m3uTitleChanged();
public slots:
    bool isQueueEmpty() const;
    bool isPlayListEmpty() const;
    void close();
    QString currentM3u() const;
    void setCurrentM3u(QString v) ;
    QString m3uTitle() const ;
    void setM3uTitle(QString t) ;
    /** called from MainMenu.qml - to decide what we are showing in the center listview */
    void setShowOption(QString option);
    QString showOption() const;
    void showPlayList();
    void on_actionSort_Playlist_triggered();
    void showSubscriptions();
    void hideSubscriptions();
    void showParentList();
    void on_actionAddFeed_triggered();
    void on_reloadButton_clicked();


    int chosenFromQML() const {return m_chosenFromQML;}
    void setChosenFromQML(int i);
    void clickEpisode(int i);
    void restoreSortedOrder();
    void sortByOption(SortDialog::Option o);
    void playQmlSelected();

    int qmlWidth() const;
    int qmlHeight() const;
    /** User selects an item in the parent list indicating we should load a playlist
        @param index in the m3uListModel */
    void openPlayListI(int index);
    /** Open a m3u file or a directory
      @param path if a folder, scans for all playable tracks in
            that directory and generates a playlist based on that
    */
    void openPlayList(QString path);
    void addToPlaylist(const QStringList& fileNames);
    /** called when user clicks on a row in the playlist */
    void jump(const QModelIndex &index);
    void seek(int seconds);
    /** Slot notified when the player changes what it is playing. */
    void updateNowPlaying(int rowIndex);
    void statusChanged(QMediaPlayer::MediaStatus status);
    void bufferingProgress(int progress);
    void displayErrorMessage();

    void on_playButton_clicked();
    void on_actionQuit_triggered();
    void on_actionOpen_triggered();
    void toggleQueue();
    void enqueue(QString urlString);
    int positionInQueue(QString urlString);
    void setTrackInfo(const QString &info);
    void setStatusInfo(const QString &info);
    void handleCursor(QMediaPlayer::MediaStatus status);
    void updateTrackInfo();
    void updateStatusInfo();
    void updateState(QMediaPlayer::State state);
    void updateDurationInfo(qint64 currentInfo);
    void updatePositionInfo(qint64 positionInfo);

    // Auto-generated slots connected to designer ui signals:
private slots:
    void disableSeekUpdates();
    void enableSeekUpdates();
    void on_previousButton_clicked();
    void on_nextButton_clicked();
    void on_actionPlay_Pause_triggered();
    void on_actionAbout_triggered();
    void on_actionAboutQt_triggered();
    void on_actionVolumeToggle_toggled(bool );

    void on_actionVolumeUp_triggered();
    void on_actionVolumeDown_triggered();
    void on_actionNextTrack_triggered();
    void on_actionPreviousTrack_triggered();

    void on_actionAdd_Playlist_Dir_triggered();
    void on_actionClear_Settings_triggered();
    void on_actionAdd_Song_Dir_triggered();
    void on_actionShuffle_triggered();
    void showVolumeSliderBriefly();
    void on_actionSet_Podcast_Dir_triggered();

    // called between tracks from the regular playlists - check
    // if something is queued.
    void checkQueue();
    // called between tracks when the queue is playing
    void updateQueue(int i);

    /** @return a QDeclarativeItem loaded from a .qml file,
        that we can add to a graphicsscene ourselves */
    QDeclarativeItem* createFromResource(QString url);

    void on_nextButton_pressed();

    void on_nextButton_released();
    void jumpAhead();
    void jumpBackward();

    void on_previousButton_pressed();

    void on_previousButton_released();

    void on_durationButton_clicked(bool checked);

    void on_actionHelp_triggered();

private:
    QMediaPlayer* newPlayer();
    Ui::MainWindow *ui;
    qint64 m_position;   // in seconds
    qint64 m_duration;   // in seconds
    bool m_showElapsed;
    QMediaPlayer::State m_state;
    QString m_statusInfo;
    QString m_trackInfo;
    // What is selected from the MainMenu:
    QString m_showOption;
    bool m_seekUpdates;
    QMediaPlayer *m_player;
    QString m_currentPlaylist;
    QMediaPlaylist *m_playList;
    QMediaPlaylist *m_queue;

    PlayListListModel *m_m3uListModel;
    SubscriptionListModel *m_subscriptionListModel;   
    QAbstractListModel *m_currentParentModel;
    PlaylistModel *m_playListModel;
    ItemsListModel* m_itemsListModel;
    QDeclarativeItem *m_flickableView;

    QDeclarativeItem *m_parentListView;
    QDeclarativeItem *m_playListView;
    QDeclarativeItem *m_podcastView;
    QDeclarativeItem *m_mainMenu;
    QDeclarativeItem *m_subscriptionView;
    QDeclarativeItem *m_helpDialog;
    QString m_m3utitle;
    int m_chosenFromQML;
    QTime m_pressedTime;
    QTimer m_fastForwardTimer;
    QTimer m_rewindTimer;
    bool m_fastForward, m_rewind;
    static MainWindow* sm_instance;    

};

#endif // MAINWINDOW_H
